#pragma once

#include <ReactCommon/CallInvoker.h>
#include <ReactCommon/CallInvokerHolder.h>
// #include <fbjni/fbjni.h>
#include <jsi/jsi.h>
#include <memory>
#include <react/jni/JRuntimeExecutor.h>

#include "JniPlatformContext.h"
#include "RNSkAndroidPlatformContext.h"
#include "RNSkLog.h"
#include "RNSkManager.h"

namespace RNSkia {
class RNSkManager;

namespace jsi = facebook::jsi;

using JavaPlatformContext = jni::alias_ref<JniPlatformContext::javaobject>;

class JniSkiaManager : public jni::HybridClass<JniSkiaManager> {
public:
    static auto constexpr kJavaDescriptor = "Lcom/shopify/reactnative/skia/SkiaManager;";
    static auto constexpr TAG = "ReactNativeSkia";

    static jni::local_ref<jni::HybridClass<JniSkiaManager>::jhybriddata> initHybrid(jni::alias_ref<jhybridobject> jThis,
        jlong jsContext, jni::alias_ref<facebook::react::JRuntimeExecutor::javaobject> jRuntimeExecutor,
        JavaPlatformContext platformContext);

    static void registerNatives();

    JniSkiaManager() {}
    ~JniSkiaManager()
    {
        RNSkLogger::logToConsole("JniSkiaManager dtor");
    }

    explicit JniSkiaManager(jni::alias_ref<JniSkiaManager::jhybridobject> jThis, jsi::Runtime *runtime,
        std::shared_ptr<facebook::react::CallInvoker> jsCallInvoker, JniPlatformContext *platformContext)
        : _javaPart(jni::make_global(jThis)),
          _jsRuntime(runtime),
          _jsCallInvoker(jsCallInvoker),
          _context(std::make_shared<RNSkAndroidPlatformContext>(platformContext, runtime, jsCallInvoker))
    {}

    std::shared_ptr<RNSkAndroidPlatformContext> getPlatformContext()
    {
        return _context;
    }
    std::shared_ptr<RNSkManager> getSkiaManager()
    {
        return _skManager;
    }

    void invalidate()
    {
        _context->stopDrawLoop();
        _context->notifyDrawLoop(true);
        _skManager = nullptr;
        _context = nullptr;
    }

private:
    friend HybridBase;

    std::shared_ptr<RNSkManager> _skManager;

    jni::global_ref<JniSkiaManager::javaobject> _javaPart;

    jsi::Runtime *_jsRuntime;
    std::shared_ptr<facebook::react::CallInvoker> _jsCallInvoker;
    std::shared_ptr<RNSkAndroidPlatformContext> _context;

    void initializeRuntime();
};
} // namespace RNSkia
